package xyz.fivefaith.tool.boot.resolver;

/**
 * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
 *
 * <p>Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 *
 * <p>http://www.gnu.org/licenses/lgpl.html
 *
 * <p>Unless required by applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing permissions and
 * limitations under the License.
 */
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.jetbrains.annotations.NotNull;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver;

import xyz.fivefaith.tool.boot.annotation.Trim;

/**
 * 自定义参数解析器 注: 自定义参数解析器, 实现对RequestResponseBodyMethodProcessor的扩展 提示: 此解析器要实现的功能是:
 * 若controller方法的参数前, 使用了@RequestBody注解, 那么解析此参数时，
 * 1、若Content-Type为application/x-www-form-urlencoded， 那么走ServletModelAttributeMethodProcessor解析器
 * 2、若Content-Type不为application/x-www-form-urlencoded， 那么走本应该走的RequestResponseBodyMethodProcessor解析器
 *
 * @author zac
 */
@Slf4j
@AllArgsConstructor
public class TrimArgumentResolver extends AbstractNamedValueMethodArgumentResolver {

    /**
     * 入参筛选
     *
     * @param methodParameter 参数集合
     * @return 格式化后的参数
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(Trim.class);
    }

    @NotNull
    @Override
    protected NamedValueInfo createNamedValueInfo(@NotNull MethodParameter parameter) {
        return new TrimNamedValueInfo();
    }

    @Override
    protected Object resolveName(
            @NotNull String name, @NotNull MethodParameter parameter, NativeWebRequest request) {
        Object arg = null;
        String[] paramValues = request.getParameterValues(name);
        if (paramValues != null) {
            arg = (paramValues.length == 1 ? paramValues[0].trim() : paramValues);
        }
        return arg;
    }

    private static class TrimNamedValueInfo extends NamedValueInfo {

        public TrimNamedValueInfo() {
            super("", false, null);
        }
    }
}
